package com.dragon.mmochat.message;

import java.util.ArrayList;
import java.util.Collections;
import java.util.List;
import java.util.Map.Entry;

import com.dragon.mmochat.MmochatConstant;
import com.dragon.mmochat.model.battle.MmochatBattle;
import com.dragon.mmochat.model.battle.MmochatHit;
import com.dragon.mmochat.model.battle.MmochatRoundFrame;
import com.dragon.mmochat.model.battle.MmochatRoundStateAddRole;
import com.dragon.mmochat.model.battle.MmochatRoundStateChange;
import com.dragon.mmochat.model.role.MmochatPlayer;
import com.dragon.mmochat.model.skill.MmochatSkill;
import com.skymobi.buffer.SkymobiBuffer;
import com.skymobi.message.SkymobiProtocolMessage;

public class Mmochat_3_13S extends SkymobiProtocolMessage {
	MmochatBattle battle;
	Integer petId = null;
	MmochatPlayer me = null;
	int totalAttackNum; // 总操作数
	List<MmochatRoundFrame> frames = new ArrayList<MmochatRoundFrame>();

	public Mmochat_3_13S() {
		setMsgCode(MmochatConstant.MSGCODE_MMOCHAT_S_3_13);
	}

	@Override
	protected void encodeBody(SkymobiBuffer out) {
		out.putInt(battle.getBattleId());
		out.putUnsigned((short) battle.getTurn());
		out.put((byte) totalAttackNum);

		out.put((byte) frames.size());
		for (MmochatRoundFrame frame : frames) {
			out.put((byte) frame.getPos());
			if (frame.getErrMsg() == null) {
				out.put((byte) 0);
			} else {
				out.putPrefixedString(frame.getErrMsg(), 1);
			}
			out.putUnsigned((short) frame.getActionType().getValue());
			out.put((byte) frame.getTargetHit().size());
			for (MmochatHit hitState : frame.getTargetHit()) {
				byte hit;
				if (hitState.isHit()) {
					hit = 1;
				} else {
					hit = 0;
				}
				out.put((byte) hitState.getPos());
				out.put(hit);
			}
			out.put((byte) (frame.getNewRoles_changeState().size()
					+ frame.getNewRoles_delRole().size() + frame
					.getNewRoles_addRole().size()));			
			for (Entry<Byte, Integer> entry : frame.getNewRoles_delRole()
					.entrySet()) {
				int pos = entry.getKey();
				out.put((byte) 1); // 删除角色
				out.put((byte) pos);
			}
			for (Entry<Byte, MmochatRoundStateAddRole> entry : frame
					.getNewRoles_addRole().entrySet()) {
				MmochatRoundStateAddRole role = entry.getValue();
				int pos = entry.getKey();
				out.put((byte) 2); // 增加角色
				out.put((byte) pos);
				out.putUnsignedShort(role.getBmpType().getValue());
				out.putPrefixedString(role.getName(), 1);
				out.putUnsignedInt(role.getSmeValue());
				out.putInt(role.getTotalBlood());
				out.putInt(role.getCurPkBlood());
				out.putInt(role.getTotalSprit());
				out.putInt(role.getCurPkSprit());
				
				
				// 技能
				if (role.getRoleType() == MmochatRoundStateAddRole.人物
						&& me != null && me.getId() == role.getId()) {
					// 更新人物
					// 法术技能
					List<MmochatSkill> attackSkills = new ArrayList<MmochatSkill>();
					for (MmochatSkill skill : role.getSkills().values()) {
						if (skill.getType().getSkillType() == MmochatSkill.攻击技能) {
							attackSkills.add(skill);
						}
					}
					if (attackSkills.size() == 0) {
						out.put((byte) 0);
					} else {
						out.put((byte) attackSkills.size());
						// 排序
						List<MmochatSkill> orderSkill = new ArrayList<MmochatSkill>(
								attackSkills);
						Collections.sort(orderSkill);
						for (MmochatSkill skill : orderSkill) {
							out.put((byte) skill.getType().getActionType()
									.getValue());
							out
									.putPrefixedString(skill.getType()
											.toString(), 1);
							out.putInt(skill.getCostSprit(true));
						}
					}
					// 障碍技能
					List<MmochatSkill> limitSkills = new ArrayList<MmochatSkill>();
					for (MmochatSkill skill : role.getSkills().values()) {
						if (skill.getType().getSkillType() == MmochatSkill.障碍技能) {
							limitSkills.add(skill);
						}
					}
					if (limitSkills.size() == 0) {
						out.put((byte) 0);
					} else {
						out.put((byte) limitSkills.size());
						// 排序
						List<MmochatSkill> orderSkill = new ArrayList<MmochatSkill>(
								limitSkills);
						Collections.sort(orderSkill);
						for (MmochatSkill skill : orderSkill) {
							out.put((byte) skill.getType().getActionType()
									.getValue());
							out
									.putPrefixedString(skill.getType()
											.toString(), 1);
							out.putInt(skill.getCostSprit(true));
						}
					}					
				} else if (petId == null || petId != role.getId()
						|| role.getRoleType() != MmochatRoundStateAddRole.宠物) {
					out.put((byte) 0);
					out.put((byte) 0);
				} else {
					// 更新宠物
					List<MmochatSkill> attackSkills = new ArrayList<MmochatSkill>();
					for (MmochatSkill skill : role.getSkills().values()) {
						if (skill.getType().getSkillType() == 0) {
							attackSkills.add(skill);
						}
					}
					// 法术技能,只有在召唤自己的宠物时才需要下发法术技能
					if (attackSkills.size() == 0) {
						out.put((byte) 0);
					} else {
						out.put((byte) attackSkills.size());
						// 排序
						List<MmochatSkill> orderSkill = new ArrayList<MmochatSkill>(
								attackSkills);
						Collections.sort(orderSkill);
						for (MmochatSkill skill : orderSkill) {
							out.put((byte) skill.getType().getActionType()
									.getValue());
							out
									.putPrefixedString(skill.getType()
											.toString(), 1);
							out.putInt(skill.getCostSprit(true));
						}
					}
					// 障碍技能
					out.put((byte) 0);
				}				
			}
			for (Entry<Byte, MmochatRoundStateChange> entry : frame
					.getNewRoles_changeState().entrySet()) {
				MmochatRoundStateChange state = entry.getValue();
				int pos = entry.getKey();
				out.put((byte) 0); // 改变状态
				out.put((byte) pos);
				out.putUnsignedInt(state.getSmeValue());
				out.putInt(state.getCurPkBlood());
				out.putInt(state.getCurPkSprit());
			}
		}
	}

	public void setBattle(MmochatBattle battle) {
		this.battle = battle;
	}

	public void setPetId(Integer petId) {
		this.petId = petId;
	}

	public void setTotalAttackNum(int totalAttackNum) {
		this.totalAttackNum = totalAttackNum;
	}

	public void setFrames(List<MmochatRoundFrame> frames) {
		this.frames = frames;
	}

	public void setMe(MmochatPlayer me) {
		this.me = me;
	}

}
